/*     */ package com.zimbra.cs.gal;
/*     */ 
/*     */ import com.google.common.collect.ImmutableMap;
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.account.Key.CacheEntryBy;
/*     */ import com.zimbra.common.account.Key.DistributionListBy;
/*     */ import com.zimbra.common.account.Key.DomainBy;
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.mailbox.ContactConstants;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.AdminConstants;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.soap.SoapProtocol;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ThreadPool;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.AccessManager;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.AccountServiceException;
/*     */ import com.zimbra.cs.account.AuthToken;
/*     */ import com.zimbra.cs.account.Domain;
/*     */ import com.zimbra.cs.account.EntryCacheDataKey;
/*     */ import com.zimbra.cs.account.GalContact;
/*     */ import com.zimbra.cs.account.Group;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Provisioning.CacheEntry;
/*     */ import com.zimbra.cs.account.accesscontrol.Rights.User;
/*     */ import com.zimbra.cs.mailbox.Contact;
/*     */ import com.zimbra.cs.service.AuthProvider;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import com.zimbra.soap.type.GalSearchType;
/*     */ import java.util.HashMap;
/*     */ import java.util.HashSet;
/*     */ import java.util.Map;
/*     */ import java.util.Map.Entry;
/*     */ import java.util.Set;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public abstract class GalGroup
/*     */ {
/*     */   public static enum GroupInfo
/*     */   {
/*  57 */     IS_GROUP, 
/*  58 */     CAN_EXPAND;
/*     */     
/*     */     private GroupInfo() {} }
/*  61 */   private static final Provisioning prov = ;
/*  62 */   private static Map<String, DomainGalGroupCache> groups = new HashMap();
/*  63 */   private static ThreadPool syncGalGroupThreadPool = new ThreadPool("SyncGalGroup", 10);
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static void flushCache(Provisioning.CacheEntry[] domains)
/*     */     throws ServiceException
/*     */   {
/*  74 */     if (domains != null) {
/*  75 */       for (Provisioning.CacheEntry entry : domains) {
/*  76 */         Key.DomainBy domainBy = entry.mEntryBy == Key.CacheEntryBy.id ? Key.DomainBy.id : Key.DomainBy.name;
/*  77 */         Domain domain = prov.get(Key.DomainBy.name, entry.mEntryIdentity);
/*  78 */         if (domain == null)
/*  79 */           throw AccountServiceException.NO_SUCH_DOMAIN(entry.mEntryIdentity);
/*  80 */         flushCache(domain);
/*     */       }
/*     */     } else {
/*  83 */       flushCache((Domain)null);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   private static abstract interface GalGroupCache
/*     */   {
/*     */     public abstract boolean isInternalGroup(String paramString);
/*     */     
/*     */ 
/*     */     public abstract boolean isExternalGroup(String paramString);
/*     */   }
/*     */   
/*     */ 
/*     */   public static boolean isGroup(String addr, Account requestedAcct)
/*     */   {
/* 100 */     return GroupInfo.IS_GROUP == GalGroupInfoProvider.getInstance().getGroupInfo(addr, false, requestedAcct, null);
/*     */   }
/*     */   
/*     */   public static GroupInfo getGroupInfo(String addr, boolean needCanExpand, Account requestedAcct, Account authedAcct) {
/* 104 */     ZimbraLog.gal.trace("GalGroup - getting group info for addr [%s] requestedAcct [%s] authedAcct [%s]", new Object[] { addr, requestedAcct, authedAcct });
/* 105 */     Domain domain = null;
/*     */     try {
/* 107 */       domain = prov.getDomain(requestedAcct);
/*     */     } catch (ServiceException e) {
/* 109 */       ZimbraLog.gal.warn("GalGroup - unable to get domain for account " + requestedAcct, e);
/*     */     }
/*     */     
/* 112 */     if ((domain == null) || (!domain.isGalGroupIndicatorEnabled())) {
/* 113 */       ZimbraLog.gal.trace("GalGroup - domain null or gal group indicator disabled [%s]", new Object[] { domain });
/* 114 */       return null;
/*     */     }
/*     */     
/* 117 */     GalGroupCache galGroup = null;
/*     */     try
/*     */     {
/* 120 */       galGroup = getGalGroupForDomain(requestedAcct, domain);
/*     */     } catch (GalGroupCacheFullException e) {
/* 122 */       ZimbraLog.gal.trace("GalGroup - cache full exception", e);
/* 123 */       return null;
/*     */     }
/*     */     
/* 126 */     if (galGroup == null)
/*     */     {
/*     */ 
/* 129 */       galGroup = new EmailAddrGalGroupCache(addr, requestedAcct);
/*     */     }
/*     */     
/*     */ 
/* 133 */     if (galGroup.isInternalGroup(addr)) {
/* 134 */       ZimbraLog.gal.trace("GalGroup - internal group");
/* 135 */       if ((needCanExpand) && (canExpandGroup(prov, addr, authedAcct))) {
/* 136 */         return GroupInfo.CAN_EXPAND;
/*     */       }
/* 138 */       return GroupInfo.IS_GROUP; }
/* 139 */     if (galGroup.isExternalGroup(addr)) {
/* 140 */       ZimbraLog.gal.trace("GalGroup - external group");
/* 141 */       if (needCanExpand) {
/* 142 */         return GroupInfo.CAN_EXPAND;
/*     */       }
/* 144 */       return GroupInfo.IS_GROUP;
/*     */     }
/* 146 */     ZimbraLog.gal.trace("GalGroup - neither internal nor external group");
/*     */     
/* 148 */     return null;
/*     */   }
/*     */   
/*     */   public static synchronized void flushCache(Domain domain) {
/* 152 */     if (domain == null) {
/* 153 */       Map<String, DomainGalGroupCache> tmp = ImmutableMap.copyOf(groups);
/* 154 */       for (Map.Entry<String, DomainGalGroupCache> entry : tmp.entrySet()) {
/* 155 */         flushCache((String)entry.getKey(), (DomainGalGroupCache)entry.getValue());
/*     */       }
/*     */     } else {
/* 158 */       String domainName = domain.getName();
/* 159 */       DomainGalGroupCache galGroup = (DomainGalGroupCache)groups.get(domainName);
/* 160 */       flushCache(domain.getName(), galGroup);
/*     */     }
/*     */   }
/*     */   
/*     */   private static void flushCache(String domainName, DomainGalGroupCache galGroup) {
/* 165 */     if (galGroup == null) {
/* 166 */       ZimbraLog.gal.info("GalGroup - flushCache: no cache entry for domain " + domainName);
/* 167 */     } else if (galGroup.isSyncing()) {
/* 168 */       ZimbraLog.gal.info("GalGroup - flushCache: Still syncing GalGroup for domain " + domainName);
/*     */     } else {
/* 170 */       ZimbraLog.gal.info("GalGroup - flushCache: Flushing GalGroup for domain " + domainName);
/* 171 */       removeFromCache(domainName, "flush cache");
/*     */     }
/*     */   }
/*     */   
/*     */   private static synchronized GalGroupCache getGalGroupForDomain(Account requestedAcct, Domain domain) throws GalGroup.GalGroupCacheFullException
/*     */   {
/* 177 */     String domainName = domain.getName();
/* 178 */     DomainGalGroupCache galGroup = (DomainGalGroupCache)groups.get(domainName);
/*     */     
/* 180 */     if (galGroup == null)
/*     */     {
/* 182 */       int maxDomains = LC.gal_group_cache_maxsize_domains.intValue();
/* 183 */       if (groups.size() >= maxDomains) {
/* 184 */         String msg = "GalGroup - group cache has reached maxsize of " + maxDomains + " domains, group indicator for messages are temporarily unavailable " + "for domain " + domainName;
/*     */         
/*     */ 
/* 187 */         if (hadWarnedDomainForCacheFull(domain))
/*     */         {
/* 189 */           ZimbraLog.gal.debug(msg);
/*     */         } else {
/* 191 */           ZimbraLog.gal.warn(msg);
/* 192 */           setHadWarnedDomainForCacheFull(domain);
/*     */         }
/* 194 */         throw new GalGroupCacheFullException(null);
/*     */       }
/*     */       
/*     */ 
/*     */ 
/*     */ 
/* 200 */       clearHadWarnedDomainForCacheFull(domain);
/*     */       
/* 202 */       galGroup = new DomainGalGroupCache(domainName, null);
/* 203 */       putInCache(domainName, galGroup);
/* 204 */       GalGroup.DomainGalGroupCache.SyncThread syncThread = new GalGroup.DomainGalGroupCache.SyncThread(domain, galGroup, null);
/* 205 */       syncGalGroupThreadPool.execute(syncThread);
/*     */     }
/*     */     
/* 208 */     if (galGroup.isSyncing()) {
/* 209 */       ZimbraLog.gal.debug("GalGroup - Still syncing GalGroup for domain " + domain.getName());
/* 210 */       return null; }
/* 211 */     if (galGroup.isExpired()) {
/* 212 */       removeFromCache(domainName, "group cache expired");
/* 213 */       return null;
/*     */     }
/* 215 */     return galGroup;
/*     */   }
/*     */   
/*     */   private static boolean hadWarnedDomainForCacheFull(Domain domain)
/*     */   {
/* 220 */     Boolean domainHadBeenWarned = (Boolean)domain.getCachedData(EntryCacheDataKey.DOMAIN_GROUP_CACHE_FULL_HAD_BEEN_WARNED.getKeyName());
/* 221 */     if (domainHadBeenWarned == null) {
/* 222 */       return false;
/*     */     }
/* 224 */     return true;
/*     */   }
/*     */   
/*     */   private static void setHadWarnedDomainForCacheFull(Domain domain) {
/* 228 */     domain.setCachedData(EntryCacheDataKey.DOMAIN_GROUP_CACHE_FULL_HAD_BEEN_WARNED.getKeyName(), Boolean.TRUE);
/*     */   }
/*     */   
/*     */   private static void clearHadWarnedDomainForCacheFull(Domain domain) {
/* 232 */     domain.setCachedData(EntryCacheDataKey.DOMAIN_GROUP_CACHE_FULL_HAD_BEEN_WARNED.getKeyName(), null);
/*     */   }
/*     */   
/*     */   private static synchronized void putInCache(String domainName, DomainGalGroupCache galGroup) {
/* 236 */     ZimbraLog.gal.debug("GalGroup - adding GalGroup cache for domain " + domainName);
/* 237 */     groups.put(domainName, galGroup);
/*     */   }
/*     */   
/*     */   private static synchronized void removeFromCache(String domainName, String reason) {
/* 241 */     ZimbraLog.gal.debug("GalGroup - removing GalGroup cache for domain " + domainName + ", " + reason);
/* 242 */     groups.remove(domainName);
/*     */   }
/*     */   
/*     */   private static boolean canExpandGroup(Provisioning prov, String groupName, Account authedAcct)
/*     */   {
/*     */     try {
/* 248 */       ZimbraLog.gal.trace("GalGroup - canExpandGroup() account [%s] group [%s]", new Object[] { authedAcct == null ? "null" : authedAcct.getName(), groupName });
/*     */       
/* 250 */       Group group = prov.getGroupBasic(Key.DistributionListBy.name, groupName);
/*     */       
/*     */ 
/*     */ 
/* 254 */       if (group == null) {
/* 255 */         ZimbraLog.gal.warn("GalGroup - unable to find group " + groupName + " for permission checking");
/* 256 */         return false;
/*     */       }
/*     */       
/* 259 */       if (!AccessManager.getInstance().canDo(authedAcct, group, Rights.User.R_viewDistList, false)) {
/* 260 */         ZimbraLog.gal.trace("GalGroup - canDo returned false");
/* 261 */         return false;
/*     */       }
/*     */     }
/*     */     catch (ServiceException e) {
/* 265 */       ZimbraLog.gal.warn("GalGroup - unable to check permission for gal group expansion: " + groupName);
/* 266 */       return false;
/*     */     }
/* 268 */     ZimbraLog.gal.trace("GalGroup - canExpandGroup() true");
/* 269 */     return true; }
/*     */   
/*     */   private static class GalGroupCacheFullException extends Exception
/*     */   {}
/*     */   
/* 274 */   private static class GalGroupCallback extends GalSearchResultCallback { protected GalGroupCallback(GalSearchParams params) { super(); }
/*     */     
/*     */     protected boolean isZimbraInternalGroup(String email, String zimbraId)
/*     */     {
/* 278 */       return (zimbraId != null) && (GalGroup.prov.isDistributionList(email));
/*     */     }
/*     */     
/*     */     protected String getSingleAttr(Object contact, String attr) {
/* 282 */       if ((contact instanceof Contact))
/* 283 */         return ((Contact)contact).get(attr);
/* 284 */       if ((contact instanceof GalContact)) {
/* 285 */         return ((GalContact)contact).getSingleAttr(attr);
/*     */       }
/* 287 */       return getSingleAttr((HashMap)contact, attr);
/*     */     }
/*     */     
/*     */     private String getSingleAttr(HashMap<String, Object> map, String attr) {
/* 291 */       Object val = map.get(attr);
/* 292 */       if ((val instanceof String))
/* 293 */         return (String)val;
/* 294 */       if ((val instanceof String[])) {
/* 295 */         return ((String[])(String[])val)[0];
/*     */       }
/* 297 */       return null;
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   private static class DomainGalGroupCache
/*     */     implements GalGroup.GalGroupCache
/*     */   {
/*     */     private String domainName;
/*     */     private long lifeTime;
/*     */     private int max;
/*     */     private boolean isSyncing;
/*     */     private Set<String> internalGroups;
/*     */     private Set<String> externalGroups;
/*     */     
/*     */     private DomainGalGroupCache(String domainName)
/*     */     {
/* 314 */       this.lifeTime = 0L;
/* 315 */       this.max = LC.gal_group_cache_maxsize_per_domain.intValue();
/*     */       
/* 317 */       this.domainName = domainName;
/* 318 */       this.isSyncing = true;
/* 319 */       this.internalGroups = new HashSet();
/* 320 */       this.externalGroups = new HashSet();
/*     */     }
/*     */     
/*     */     private synchronized boolean isSyncing() {
/* 324 */       return this.isSyncing;
/*     */     }
/*     */     
/*     */     private synchronized boolean isExpired() {
/* 328 */       return (!this.isSyncing) && (this.lifeTime < System.currentTimeMillis());
/*     */     }
/*     */     
/*     */     private synchronized void setDoneSyncing() {
/* 332 */       this.isSyncing = false;
/*     */       
/*     */ 
/* 335 */       this.lifeTime = (System.currentTimeMillis() + LC.gal_group_cache_maxage.intValueWithinRange(15, 43200) * 60000L);
/*     */     }
/*     */     
/*     */     private void addInternalGroup(String addr)
/*     */     {
/* 340 */       if (reachedMax()) {
/* 341 */         ZimbraLog.gal.debug("GalGroup - NOT adding internal group: " + addr + ", limit (" + this.max + ") reached, domain=" + this.domainName);
/* 342 */         return;
/*     */       }
/*     */       
/* 345 */       ZimbraLog.gal.debug("GalGroup - Adding internal group: " + addr + ", domain=" + this.domainName);
/* 346 */       this.internalGroups.add(addr.toLowerCase());
/*     */     }
/*     */     
/*     */     private void addExternalGroup(String addr)
/*     */     {
/* 351 */       if (reachedMax()) {
/* 352 */         ZimbraLog.gal.debug("GalGroup - NOT adding external group: " + addr + ", limit (" + this.max + ") reached, domain=" + this.domainName);
/* 353 */         return;
/*     */       }
/*     */       
/* 356 */       ZimbraLog.gal.debug("GalGroup - Adding external group: " + addr + ", domain=" + this.domainName);
/* 357 */       this.externalGroups.add(addr.toLowerCase());
/*     */     }
/*     */     
/*     */     private boolean reachedMax() {
/* 361 */       if (this.max == 0) {
/* 362 */         return false;
/*     */       }
/* 364 */       return this.internalGroups.size() + this.externalGroups.size() >= this.max;
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */     public boolean isInternalGroup(String addr)
/*     */     {
/* 371 */       return this.internalGroups.contains(addr.toLowerCase());
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */     public boolean isExternalGroup(String addr)
/*     */     {
/* 378 */       return this.externalGroups.contains(addr.toLowerCase());
/*     */     }
/*     */     
/*     */     private int getMax() {
/* 382 */       return this.max;
/*     */     }
/*     */     
/*     */     private static class SyncThread implements Runnable {
/*     */       AuthToken adminAuthToken;
/*     */       Domain domain;
/*     */       GalGroup.DomainGalGroupCache galGroup;
/*     */       
/*     */       private SyncThread(Domain domain, GalGroup.DomainGalGroupCache galGroup) {
/* 391 */         this.domain = domain;
/* 392 */         this.galGroup = galGroup;
/*     */       }
/*     */       
/*     */       public void run()
/*     */       {
/*     */         try
/*     */         {
/* 399 */           Account admin = Provisioning.getInstance().get(Key.AccountBy.adminName, LC.zimbra_ldap_user.value());
/* 400 */           ZimbraLog.addAccountNameToContext(admin.getName());
/* 401 */           this.adminAuthToken = AuthProvider.getAuthToken(admin, true);
/*     */           
/* 403 */           long startTime = System.currentTimeMillis();
/* 404 */           ZimbraLog.gal.info("GalGroup - Start syncing gal groups for domain " + this.domain.getName());
/*     */           
/* 406 */           sync();
/* 407 */           this.galGroup.setDoneSyncing();
/*     */           
/* 409 */           long elapsedTime = System.currentTimeMillis() - startTime;
/* 410 */           ZimbraLog.gal.info("GalGroup - Finished syncing gal groups for domain " + this.domain.getName() + ", elapsed time = " + elapsedTime + "msec");
/*     */         }
/*     */         catch (ServiceException e) {
/* 413 */           ZimbraLog.gal.warn("GalGroup - failed to sync gal groups for domain " + this.domain.getName(), e);
/* 414 */           GalGroup.removeFromCache(this.domain.getName(), "sync failed");
/*     */         }
/*     */       }
/*     */       
/*     */       private void sync() throws ServiceException
/*     */       {
/* 420 */         int offset = 0;
/* 421 */         int max = this.galGroup.getMax();
/* 422 */         int pageSize = 1000;
/* 423 */         int limit = max == 0 ? pageSize : Math.min(pageSize, max);
/*     */         
/* 425 */         GalSearchType searchType = GalSearchType.group;
/*     */         
/* 427 */         boolean hasMore = true;
/*     */         
/* 429 */         while ((hasMore) && (!this.galGroup.reachedMax())) {
/* 430 */           ZimbraSoapContext zsc = new ZimbraSoapContext(this.adminAuthToken, null, SoapProtocol.Soap12, SoapProtocol.Soap12);
/* 431 */           GalSearchParams params = new GalSearchParams(this.domain, zsc);
/*     */           
/*     */ 
/* 434 */           Element request = Element.create(SoapProtocol.Soap12, AdminConstants.SEARCH_GAL_REQUEST);
/* 435 */           request.addAttribute("domain", this.domain.getName());
/* 436 */           request.addAttribute("type", searchType.name());
/* 437 */           request.addAttribute("offset", offset);
/* 438 */           request.addAttribute("limit", limit);
/* 439 */           params.setRequest(request);
/*     */           
/* 441 */           params.setType(searchType);
/* 442 */           params.setLimit(limit);
/* 443 */           params.setLdapLimit(max);
/* 444 */           params.setResponseName(AdminConstants.SEARCH_GAL_RESPONSE);
/*     */           
/* 446 */           SyncGalGroupCallback resultCallback = new SyncGalGroupCallback(params, this.galGroup, null);
/* 447 */           params.setResultCallback(resultCallback);
/* 448 */           GalSearchControl gal = new GalSearchControl(params);
/*     */           
/* 450 */           ZimbraLog.gal.debug("GalGroup - searching GAL for groups: domain=" + this.domain.getName() + ", max=" + max + ", limit=" + limit + ", offset=" + offset);
/* 451 */           gal.search();
/*     */           
/* 453 */           offset += limit;
/*     */           
/* 455 */           if (resultCallback.isPagingSupported()) {
/* 456 */             hasMore = resultCallback.getHasMore();
/*     */           } else {
/* 458 */             hasMore = false;
/*     */           }
/*     */         }
/*     */       }
/*     */       
/*     */       private static class SyncGalGroupCallback extends GalGroup.GalGroupCallback
/*     */       {
/*     */         private GalGroup.DomainGalGroupCache galGroup;
/*     */         private boolean hasMore;
/*     */         private boolean pagingSupported;
/* 468 */         private String[] EXTRA_EMAIL_FIELDS = { "email2", "email3", "email4", "email5", "email6", "email7", "email8", "email9", "email10", "email11", "email12", "email13", "email14", "email15", "email16" };
/*     */         
/*     */ 
/*     */ 
/*     */         private SyncGalGroupCallback(GalSearchParams params, GalGroup.DomainGalGroupCache galGroup)
/*     */         {
/* 474 */           super();
/* 475 */           this.galGroup = galGroup;
/*     */         }
/*     */         
/*     */         public Element handleContact(Contact contact) throws ServiceException
/*     */         {
/* 480 */           if (!contact.isGroup()) {
/* 481 */             return null;
/*     */           }
/* 483 */           String email = getSingleAttr(contact, ContactConstants.A_email);
/* 484 */           String zimbraId = getSingleAttr(contact, ContactConstants.A_zimbraId);
/*     */           
/* 486 */           if (email == null) {
/* 487 */             ZimbraLog.gal.info("GalGroup - handle Contact: contact " + contact.getFileAsString() + "(" + contact.getId() + ")" + " does not have an email address." + " Not adding to gal group cache.");
/*     */           }
/*     */           else
/*     */           {
/* 491 */             addResult(email, zimbraId, contact);
/*     */           }
/* 493 */           return null;
/*     */         }
/*     */         
/*     */         public void handleContact(GalContact galContact) throws ServiceException
/*     */         {
/* 498 */           if (!galContact.isGroup()) {
/* 499 */             return;
/*     */           }
/* 501 */           String email = getSingleAttr(galContact, ContactConstants.A_email);
/* 502 */           String zimbraId = getSingleAttr(galContact, ContactConstants.A_zimbraId);
/*     */           
/* 504 */           if (email == null) {
/* 505 */             ZimbraLog.gal.info("GalGroup - handle GalContact: contact " + galContact.getId() + " does not have an email address." + " Not adding to gal group cache.");
/*     */           }
/*     */           else
/*     */           {
/* 509 */             addResult(email, zimbraId, galContact);
/*     */           }
/*     */         }
/*     */         
/*     */         public void handleElement(Element e) throws ServiceException
/*     */         {
/* 515 */           HashMap<String, Object> contact = parseContactElement(e);
/* 516 */           if (!Contact.isGroup(contact)) {
/* 517 */             return;
/*     */           }
/* 519 */           String email = getSingleAttr(contact, ContactConstants.A_email);
/* 520 */           String zimbraId = getSingleAttr(contact, ContactConstants.A_zimbraId);
/*     */           
/* 522 */           if (email == null) {
/* 523 */             ZimbraLog.gal.info("GalGroup - handle Element: contact " + e.toString() + " does not have an email address." + " Not adding to gal group cache.");
/*     */           }
/*     */           else
/*     */           {
/* 527 */             addResult(email, zimbraId, contact);
/*     */           }
/*     */         }
/*     */         
/*     */         private void addResult(String email, String zimbraId, Object contact) {
/* 532 */           if (isZimbraInternalGroup(email, zimbraId)) {
/* 533 */             this.galGroup.addInternalGroup(email);
/* 534 */             for (String extraEmailField : this.EXTRA_EMAIL_FIELDS) {
/* 535 */               String extraEmail = getSingleAttr(contact, extraEmailField);
/* 536 */               if (extraEmail != null)
/* 537 */                 this.galGroup.addInternalGroup(extraEmail);
/*     */             }
/*     */           } else {
/* 540 */             this.galGroup.addExternalGroup(email);
/* 541 */             for (String extraEmailField : this.EXTRA_EMAIL_FIELDS) {
/* 542 */               String extraEmail = getSingleAttr(contact, extraEmailField);
/* 543 */               if (extraEmail != null) {
/* 544 */                 this.galGroup.addExternalGroup(extraEmail);
/*     */               }
/*     */             }
/*     */           }
/*     */         }
/*     */         
/*     */         public void setQueryOffset(int offset) {
/* 551 */           this.pagingSupported = true;
/*     */         }
/*     */         
/*     */         public void setHasMoreResult(boolean more)
/*     */         {
/* 556 */           this.hasMore = more;
/*     */         }
/*     */         
/*     */         private boolean getHasMore() {
/* 560 */           return this.hasMore;
/*     */         }
/*     */         
/*     */         private boolean isPagingSupported() {
/* 564 */           return this.pagingSupported;
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   private static class EmailAddrGalGroupCache
/*     */     implements GalGroup.GalGroupCache
/*     */   {
/*     */     SearchGroupCallback resultCallback;
/*     */     
/*     */     EmailAddrGalGroupCache(String addr, Account requestedAcct)
/*     */     {
/* 578 */       GalSearchParams params = new GalSearchParams(requestedAcct);
/* 579 */       params.setQuery(addr);
/* 580 */       params.setType(GalSearchType.group);
/* 581 */       params.setLimit(1);
/* 582 */       this.resultCallback = new SearchGroupCallback(params, null);
/* 583 */       params.setResultCallback(this.resultCallback);
/*     */       
/* 585 */       GalSearchControl gal = new GalSearchControl(params);
/*     */       try {
/* 587 */         gal.search();
/*     */       } catch (ServiceException e) {
/* 589 */         ZimbraLog.gal.warn("GalGroup - unable to search GAL group for addr:" + addr, e);
/*     */       }
/*     */     }
/*     */     
/*     */     public boolean isInternalGroup(String addr)
/*     */     {
/* 595 */       return this.resultCallback.isInternalGroup();
/*     */     }
/*     */     
/*     */     public boolean isExternalGroup(String addr)
/*     */     {
/* 600 */       return this.resultCallback.isExternalGroup();
/*     */     }
/*     */     
/*     */     private static class SearchGroupCallback extends GalGroup.GalGroupCallback {
/*     */       private boolean isInternalGroup;
/*     */       private boolean isExternalGroup;
/*     */       
/*     */       private SearchGroupCallback(GalSearchParams params) {
/* 608 */         super();
/*     */       }
/*     */       
/*     */       public Element handleContact(Contact contact) throws ServiceException
/*     */       {
/* 613 */         if (!contact.isGroup()) {
/* 614 */           return null;
/*     */         }
/* 616 */         String email = getSingleAttr(contact, ContactConstants.A_email);
/* 617 */         String zimbraId = getSingleAttr(contact, ContactConstants.A_zimbraId);
/* 618 */         setResult(email, zimbraId);
/* 619 */         return null;
/*     */       }
/*     */       
/*     */       public void handleContact(GalContact galContact) throws ServiceException
/*     */       {
/* 624 */         if (!galContact.isGroup()) {
/* 625 */           return;
/*     */         }
/* 627 */         String email = getSingleAttr(galContact, ContactConstants.A_email);
/* 628 */         String zimbraId = getSingleAttr(galContact, ContactConstants.A_zimbraId);
/* 629 */         setResult(email, zimbraId);
/*     */       }
/*     */       
/*     */       public void handleElement(Element e) throws ServiceException
/*     */       {
/* 634 */         HashMap<String, Object> contact = parseContactElement(e);
/* 635 */         if (!Contact.isGroup(contact)) {
/* 636 */           return;
/*     */         }
/* 638 */         String email = getSingleAttr(contact, ContactConstants.A_email);
/* 639 */         String zimbraId = getSingleAttr(contact, ContactConstants.A_zimbraId);
/* 640 */         setResult(email, zimbraId);
/*     */       }
/*     */       
/*     */       private void setResult(String email, String zimbraId) {
/* 644 */         if (isZimbraInternalGroup(email, zimbraId)) {
/* 645 */           this.isInternalGroup = true;
/*     */         } else
/* 647 */           this.isExternalGroup = true;
/*     */       }
/*     */       
/*     */       private boolean isInternalGroup() {
/* 651 */         return this.isInternalGroup;
/*     */       }
/*     */       
/*     */       private boolean isExternalGroup() {
/* 655 */         return this.isExternalGroup;
/*     */       }
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/gal/GalGroup.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */